package com.dht.xiao.jianye.base.serialport.asyncservices.thread;

import android.os.SystemClock;
import android.text.TextUtils;

import org.greenrobot.eventbus.EventBus;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.List;

import com.dht.xiao.jianye.base.serialport.DataPack;
import com.dht.xiao.jianye.base.serialport.asyncservices.ReadType;
import com.dht.xiao.jianye.base.serialport.asyncservices.message.ReadMessage;
import com.dht.xiao.jianye.base.serialport.callback.AsyncDataCallback;
import com.dht.xiao.jianye.base.serialport.callback.BaseDataCallback;
import com.dht.xiao.jianye.base.serialport.log.SerialPortLoggerFactory;
import com.dht.xiao.jianye.base.serialport.utils.ByteUtil;

/**
 * 读串口线程
 */
public class SerialReadThread extends Thread {

    private static final String TAG = "SerialReadThread";

    private BufferedInputStream mBufferedInputStream;
    private BaseDataCallback mBaseDataCallback;
    private boolean isActivelyReceivedCommand;
    private List<byte[]> mHeartCommand;
    /**
     * 记录一下发送后的时间，用来判断接收数据是否超时
     */
    private long checkSendDataTime = System.currentTimeMillis();
    private long errorTime = System.currentTimeMillis();

    private DataPack mDataPack = null;

    public SerialReadThread(boolean isActivelyReceivedCommand, List<byte[]> heartCommand, BufferedInputStream bufferedInputStream, BaseDataCallback baseDataCallback) {
        mBufferedInputStream = bufferedInputStream;
        mBaseDataCallback = baseDataCallback;
        mHeartCommand = heartCommand;
        this.isActivelyReceivedCommand = isActivelyReceivedCommand;
    }

    @Override
    public void run() {
        byte[] received = new byte[1024];
        int size;

        SerialPortLoggerFactory.info("开始读线程");

        while (true) {
            if (Thread.currentThread().isInterrupted()) {
                break;
            }
            try {
                int available = mBufferedInputStream.available();
                boolean isSend = false;
                if (available > 0) {
                    size = mBufferedInputStream.read(received);
                    if (size > 0) {
                        isSend = onDataReceive(received, size);
                        // 暂停一点时间，免得处理数据太快
                        SystemClock.sleep(1);
                    }
                } else {
                    // 暂停一点时间，免得一直循环造成CPU占用率过高
                    SystemClock.sleep(1);
                }
                if (!isSend && isTimeOut()) {
                    //校验发送数据包
                    EventBus.getDefault().post(new ReadMessage(ReadType.CheckSendData, "CheckSendData", mDataPack));
                }
            } catch (IOException e) {
                //SerialPortLoggerFactory.error("读取数据失败:" + e.toString());
                if (isErrorTimeOut()) {
                    EventBus.getDefault().post(new ReadMessage(ReadType.CheckSendData, "ReadDataError:" +
                            "读取数据失败:" + e.toString(), null));
                }
            }
        }

        SerialPortLoggerFactory.info("结束读进程");
    }

    /**
     * 处理获取到的数据
     *
     * @param received
     * @param size
     */
    private boolean onDataReceive(byte[] received, int size) {
        mDataPack = mBaseDataCallback.checkData(received, size);
        if (mDataPack != null) {
            //SerialPortLoggerFactory.info("接收数据:" + ByteUtil.bytes2HexStr(mDataPack.getAllPackData()));
            if (isActivelyReceivedCommand && isActivelyReceivedCommand()) {
                if (mBaseDataCallback instanceof AsyncDataCallback) {
                    ((AsyncDataCallback) mBaseDataCallback).onActivelyReceivedCommand(mDataPack.getAllPackData(), mDataPack.getData(), mDataPack.getCommand());
                }
                return false;
            }
            //不是心跳数据
            EventBus.getDefault().post(new ReadMessage(ReadType.ReadDataSuccess, "ReadDataSuccess", mDataPack));
            return true;

        }
        return false;
    }

    /**
     * 是否是主动收到命令
     *
     * @return
     */
    private boolean isActivelyReceivedCommand() {
        if (mHeartCommand != null && mHeartCommand.size() > 0) {
            for (byte[] bytes : mHeartCommand) {
                String command = ByteUtil.bytes2HexStr(bytes);
                String readCommand = ByteUtil.bytes2HexStr(mDataPack.getCommand());
                if (TextUtils.equals(command, readCommand)) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isTimeOut() {
        // 在规定时间内校验
        if (Math.abs(System.currentTimeMillis() - checkSendDataTime) > 100) {
            checkSendDataTime = System.currentTimeMillis();
            return true;
        }
        return false;
    }

    private boolean isErrorTimeOut() {
        // 在规定时间内校验
        if (Math.abs(System.currentTimeMillis() - errorTime) > 1000) {
            errorTime = System.currentTimeMillis();
            return true;
        }
        return false;
    }

    /**
     * 停止读线程
     */
    public void close() {

        try {
            mBufferedInputStream.close();
        } catch (IOException e) {
            SerialPortLoggerFactory.error("异常:" + e.toString());
        } finally {
            super.interrupt();
        }
    }
}
